package JUC.第04章_锁;
/**
 * 进入相关的.class文件 右键 Open in Terminal
 * cd target\classes\JUC\第03章_锁
 * 输入
 *  javap -c .\D_synchronized的深入解析.class
 *  javap -c .\名字.class
 *  javap -c .\从字节码角度.class
 *        -v    可以输出附加信息 ( 包括行号、本地变量表，反汇)
 *
 *  m1  大概长这样
 *  public void m1();
 *     Code:
 *        0: aload_0
 *        1: getfield      #3  // Field o:Ljava/lang/Object;
 *        4: dup
 *        5: astore_1
 *        6: monitorenter
 *        7: getstatic     #4  // Field java/lang/System.out:Ljava/io/PrintStream;
 *       10: ldc           #5  // String hello
 *       12: invokevirtual #6  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
 *       15: aload_1
 *       16: monitorexit
 *       17: goto          25
 *       20: astore_2
 *       21: aload_1
 *       22: monitorexit
 *       23: aload_2
 *       24: athrow
 *       25: return
 *
 *        monitorenter  加锁
 * 第一个  monitorexit   释放
 * 第二个  monitorexit   防止异常情况出现稳定释放
 *
 * 一般情况          1个monitorenter  2个monitorexit
 * 如果主动抛出异常   1个monitorenter  1个monitorexit
 *
 * 如果是在方法上加 m2
 * //JDK 8
 * 在 flags 有    ACC_SYNCHRONIZED  ACC_PUBLIC
 * 表示这个方法是同步方法
 *
 * 如果是    m3
 * //JDK 8
 * 在 flags 有    ACC_SYNCHRONIZED  ACC_PUBLIC  ACC_STATIC
 * 表示这个方法是同步方法
 */
/**
 * 为什么synchronized会加一个对象来当锁
 * 所有类都有一个父类 Object
 * java的底层是c++    而c++源码看过后，
 * 每个对象天生都带着一个对象监视器
 * 每一个被锁住的对象都会和 Monitor (管城)关联起来
 *
 * 管程(英语: Monitors， 也称为监视器)是一种程序结构，
 * 结构内的多个子程序(对象或模块)形成的多个工作线程互访问共享资源。
 * 这些共享资源一般是硬件设备或一群变量。
 * 对共享变量能够进行的所有操作集中在一个模块中。(把信号量及其操作原语“封装”在一个对 象内部)
 * 管程实现了在一个时间点，最多只有一个线程在执行管程的某个子程序。
 * 管程提供了一种机制，管程可以看做一个软件模块，
 * 它是将共享的变量和对于这些共享变量的操作封装起来，
 * 形成一个具有一定接口的功能 模块，进程可以调用管程来实现进程级别的并发控制。
 *
 *
 */
public class D_synchronized的深入解析 {
    Object o = new Object();

    public static synchronized void m3(){System.out.println("m2");}

    public static void main(String[] args) {}

    public void m1(){
        synchronized (o){System.out.println("m1");}
    }

    public synchronized void m2(){
        System.out.println("m2");
    }
}
